﻿#pragma once

#include <string>
#include <vector>
#include "../tangible_filesystem.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace LibraryViewer { class MImage; }

namespace LibraryViewer
{
    class MLibrary final
    {
    public:
        static constexpr int LibVersion = 3;

        static bool Load;
        std::string FileName;

        std::vector<MImage*> Images = std::vector<MImage*>();

        std::vector<int> IndexList = std::vector<int>();
        int Count = 0;
    private:
        bool _initialized = false;

        BinaryReader *_reader;
        FileStream *_stream;

    public:
        virtual ~MLibrary()
        {
            delete _reader;
            delete _stream;
        }

        MLibrary(const std::string &filename);

        void Initialize();

        void Close();

    private:
        void CheckImage(int index);

    public:
        MImage *GetMImage(int index);

        Bitmap *GetPreview(int index);

        void RemoveImage(int index);

    public:
        class MImage final
        {
        public:
            short Width = 0, Height = 0, X = 0, Y = 0, ShadowX = 0, ShadowY = 0;
            unsigned char Shadow = 0;
            int Length = 0;
            std::vector<unsigned char> FBytes;
            bool TextureValid = false;
            Bitmap *Image, *Preview;

            //layer 2:
            short MaskWidth = 0, MaskHeight = 0, MaskX = 0, MaskY = 0;

            int MaskLength = 0;
            std::vector<unsigned char> MaskFBytes;
            Bitmap *MaskImage;
            bool HasMask = false;

            virtual ~MImage()
            {
                delete Image;
                delete Preview;
                delete MaskImage;
            }

            MImage(BinaryReader *reader);

//C# TO C++ CONVERTER TODO TASK: C# 'unsafe' code is not converted by C# to C++ Converter:
//            private unsafe byte[] ConvertBitmapToArray(Bitmap input)
//            {
//                BitmapData data = input.LockBits(new Rectangle(0, 0, input.Width, input.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
//
//                byte[] pixels = new byte[input.Width * input.Height * 4];
//
//                Marshal.Copy(data.Scan0, pixels, 0, pixels.Length);
//
//                input.UnlockBits(data);
//
//                for (int i = 0; i < pixels.Length; i += 4)
//                {
//                    if (pixels[i] == 0 && pixels[i + 1] == 0 && pixels[i + 2] == 0)
//                        pixels[i + 3] = 0; //Make Transparent
//                }
//
//                byte[] compressedBytes;
//                compressedBytes = Compress(pixels);
//
//                return compressedBytes;
//            }

//C# TO C++ CONVERTER TODO TASK: C# 'unsafe' code is not converted by C# to C++ Converter:
//            public unsafe void CreateTexture(BinaryReader reader)
//            {
//                int w = Width; // +(4 - Width % 4) % 4;
//                int h = Height; // +(4 - Height % 4) % 4;
//
//                if (w == 0 || h == 0)
//                    return;
//                if ((w < 2) || (h < 2))
//                    return;
//                Image = new Bitmap(w, h);
//
//                BitmapData data = Image.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
//
//                byte[] dest = Decompress(FBytes);
//
//                Marshal.Copy(dest, 0, data.Scan0, dest.Length);
//
//                Image.UnlockBits(data);
//
//                dest = nullptr;
//
//                if (HasMask)
//                {
//                    w = MaskWidth; // +(4 - MaskWidth % 4) % 4;
//                    h = MaskHeight; // +(4 - MaskHeight % 4) % 4;
//
//                    if (w == 0 || h == 0)
//                    {
//                        return;
//                    }
//
//                    try
//                    {
//                        MaskImage = new Bitmap(w, h);
//
//                        data = MaskImage.LockBits(new Rectangle(0, 0, w, h), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
//
//                        dest = Decompress(MaskFBytes);
//
//                        Marshal.Copy(dest, 0, data.Scan0, dest.Length);
//
//                        MaskImage.UnlockBits(data);
//                    }
//                    catch (Exception ex)
//                    {
//                        File.AppendAllText(R"(.\Error.txt)", string.Format("[{0}] {1}{2}", DateTime.Now, ex, Environment.NewLine));
//                    }
//                }
//
//                dest = nullptr;
//            }

            static std::vector<unsigned char> Compress(std::vector<unsigned char> &raw);

        private:
            static std::vector<unsigned char> Decompress(std::vector<unsigned char> &gzip);

        public:
            void CreatePreview();
        };
    };
}
